#include "clientsocket.h"
#include<QJsonObject>
#include<myapp.h>

ClientSocket::ClientSocket(QObject *parent)
    : QObject(parent),
    m_nId(-1),
    m_tcpSocket(nullptr)
{
    //创建客户端套接字
    m_tcpSocket=new QTcpSocket();

    //连接槽函数
    connect(m_tcpSocket,&QTcpSocket::connected,this,&ClientSocket::SltConnected);
    connect(m_tcpSocket,&QTcpSocket::readyRead,this,&ClientSocket::SltReadyRead);
    connect(m_tcpSocket,&QTcpSocket::disconnected,this,&ClientSocket::SltDisconnected);



}

ClientSocket::~ClientSocket()
{

}

int ClientSocket::GetUserId() const//获取用户id
{
    return m_nId;
}

void ClientSocket::SetUserId(const int &id)//改变id
{
    m_nId=id;
}

//连接状态管理
void ClientSocket::CheckConnected()//进行重连:应用发消息前的检查，
{
    //检查socket是否连接到服务器
    if(m_tcpSocket->state()!=QTcpSocket::ConnectedState)
    {
        //如果未连接进行重连
        m_tcpSocket->connectToHost(MyApp::m_strHostAddr, MyApp::m_nMsgPort);
    }
}

void ClientSocket::ColseConnected()//断开连接：用户主动退出，切换服务器
{
    if (m_tcpSocket->isOpen()) {
        m_tcpSocket->abort();  // 立即中止连接
    } //断开服务器用abort，断开槽函数用disconnct
}

void ClientSocket::ConnectToHost(const QString &host, const int &port)
{
    if (m_tcpSocket->isOpen()) {
        m_tcpSocket->abort();  // 立即中止连接
    } //断开服务器用abort，断开槽函数用disconnct
    m_tcpSocket->connectToHost(host,port);//连接指定的ip
}

void ClientSocket::ConnectToHost(const QHostAddress &host, const int &port)
{
    if (m_tcpSocket->isOpen()) {
        m_tcpSocket->abort();  // 立即中止连接
    } //断开服务器用abort，断开槽函数用disconnct
    m_tcpSocket->connectToHost(host,port);
}

void ClientSocket::SltSendMessage(const quint8 &type,const QJsonValue &dataVal)
{
    qDebug() << "=== 开始发送消息 ===";
    qDebug() << "当前Socket状态:" << m_tcpSocket->state();
    if(!m_tcpSocket->isOpen())//进行断线重连
    {
        m_tcpSocket->connectToHost(MyApp::m_strHostAddr, MyApp::m_nMsgPort);
        m_tcpSocket->waitForConnected(1000);//阻塞等待连接建立
    }
    if(!m_tcpSocket->isOpen()){qDebug() << "❌ 无法连接到服务器，消息发送失败";return;};
    //构建json消息结构
    QJsonObject json;
    json.insert("type",type);//消息类型
    json.insert("from",m_nId);//发送者id
    json.insert("data",dataVal);//消息数据
    //序列化发送
    QJsonDocument document;
    document.setObject(json);
    m_tcpSocket->write(document.toJson(QJsonDocument::Compact));//QJsonDocument::Compact参数表示生成紧凑格式（无空格和换行）
}

void ClientSocket::SltSendOnline()
{
  //上线是候给当前好友发状态

}

void ClientSocket::SltConnected()
{
    qDebug() << "has connecetd";
    Q_EMIT signalStatus(ConnectedHost);//这个代码的作用是为了传个登录窗口，然后进行相应的代码处理
}
void ClientSocket::SltDisconnected()
{   qDebug() << "has disconnecetd";
    if (m_tcpSocket->isOpen()) {
        m_tcpSocket->abort();  // 立即中止连接
    } //断开服务器用abort，断开槽函数用disconnct
    Q_EMIT signalStatus(DisConnectedHost);
}

void ClientSocket::ParseLogin(const QJsonValue &dataVal)
{
    if(dataVal.isObject())
    {
        QJsonObject dataObj=dataVal.toObject();
        int code =dataObj.value("code").toInt();//状态码
        QString msg=dataObj.value("msg").toString();//消息文本
        QString strHead=dataObj.value("head").toString();//头像文件名
        if(0==code&&msg=="ok")
        {
            m_nId=dataObj.value("id").toInt();//获取用户ID
            MyApp::m_strHeadFile = MyApp::m_strHeadPath + strHead;
            MyApp::m_nId = m_nId;                      // 保存到全局变量
            Q_EMIT signalStatus(LoginSuccess);
        }
        else if(-1==code)
        {
            Q_EMIT signalStatus(LoginPasswdError);
        }
        else if(-2==code)
        {
            Q_EMIT signalStatus(LoginRepeat);
        }
    }
}

void ClientSocket::ParseReister(const QJsonValue &dataVal)
{
    if(dataVal.isObject())
    {
        QJsonObject dataObj=dataVal.toObject();
        m_nId=dataObj.value("id").toInt();//获取分配的id
        if(-1!=m_nId)
        {
            Q_EMIT signalStatus(RegisterOk);
        }
        else
        {
            Q_EMIT signalStatus(RegisterFailed);
        }
    }
}


void ClientSocket::SltReadyRead()
{
    //读取内容
    QByteArray byRead=m_tcpSocket->readAll();
    qDebug() << "📨 收到服务器原始数据:" << byRead;  // 添加调试信息

    //解析读取数据为json
    QJsonParseError jsonerror;
    QJsonDocument document=QJsonDocument::fromJson(byRead,&jsonerror);
    if(!document.isNull()&&(jsonerror.error==QJsonParseError::NoError))
    {
        if(document.isObject())
        {  //转文件为文档
            QJsonObject jsonobj=document.object();
            QJsonValue dataVal=jsonobj.value("data");
            int nType=jsonobj.value("type").toInt();
            int fromid=jsonobj.value("from").toInt();
            //根据小i类型解析服务器消息

                switch (nType) {
                case Register:
                {
                    ParseReister(dataVal);
                }
                break;
                case Login:
                {
                    ParseLogin(dataVal);
                }
                break;
                case OnLine:
                {
                    qDebug() << "user is oline" << dataVal;
                    Q_EMIT signalMessage(OnLine, dataVal);
                }
                break;
                case OffLine:
                {
                    qDebug() << "user is offline" << dataVal;
                    Q_EMIT signalMessage(OffLine, dataVal);
                }
                break;
                case Logout:
                {
                    m_tcpSocket->abort();
                }
                break;
                case UpdateHeadPic:
                {
                    Q_EMIT signalMessage(UpdateHeadPic, dataVal);
                }
                break;

                case AddGroup:
                {
                    Q_EMIT signalMessage(AddGroup, dataVal);
                }
                break;
                case AddFriendRequist:
                {
                    Q_EMIT signalMessage(AddFriendRequist, dataVal);
                }
                break;
                case AddGroupRequist:
                {
                    Q_EMIT signalMessage(AddGroupRequist, dataVal);
                }
                break;
                case CreateGroup:
                {
                    Q_EMIT signalMessage(CreateGroup, dataVal);
                }
                break;
                case GetMyFriends:
                {
                    Q_EMIT signalMessage(GetMyFriends, dataVal);
                }
                break;
                case GetMyGroups:
                {
                    Q_EMIT signalMessage(GetMyGroups, dataVal);
                }
                break;
                case RefreshFriends:
                {
                    Q_EMIT signalMessage(RefreshFriends, dataVal);
                }
                break;
                case RefreshGroups:
                {
                    Q_EMIT signalMessage(RefreshGroups, dataVal);
                }
                break;
                case SendMsg:
                {
                    Q_EMIT signalMessage(SendMsg, dataVal);
                }
                break;
                case SendGroupMsg:
                {
                    Q_EMIT signalMessage(SendGroupMsg, dataVal);
                }
                break;
                case SendFile:
                {
                    Q_EMIT signalMessage(SendFile, dataVal);
                }
                break;
                case SendPicture:
                {
                    Q_EMIT signalMessage(SendPicture, dataVal);
                }
                break;
                default:
                    break;
                }

            }
        }
    }




